;;;; -*- Mode: LISP; Package: cl-user -*-

(in-package :cl-user)

;;;;
;;;; game-editor.lisp
;;;;


(defparameter *default-image* (make-instance 'ns:ns-image
					     :init-by-referencing-file 
					     #@"/Users/millejoh/Applications/dreaming-tree/data/balance_chipmunk.png"))

(defclass simple-space-editor (ns:ns-window-controller)
  ((space :accessor space :initarg :space)
   (shape-browser :foreign-type :id :accessor shape-browser)
   (shape-tree :foreign-type :id :accessor shape-tree)
   (shape-editor :foreign-type :id :accessor shape-editor)
   (shape-list :foreign-type :id :reader shape-list :initform +null-ptr+)
   (selected-object :foreign-type :id :accessor selected-object :initform +null-ptr+))
  (:metaclass ns:+ns-object))

(defclass shape-item-view (ns:ns-view)
  ((delegate :foreign-type :id :accessor delegate))
  (:metaclass ns:+ns-object))

(objc:defmethod (#/copyWithZone: :id) ((self shape-item-view) zone)
  (let ((copy (#/initWithFrame: (#/allocWithZone: shape-item-view zone)
				(#/frame self))))
    (setf (delegate copy) (delegate self))
    copy))

(objc:defmethod (#/acceptsFirstResponder #>BOOL) ((self shape-item-view))
  #$YES)

(objc:defmethod (#/hitTest: :id) ((self shape-item-view) point)
  (if (#_NSPointInRect point (#/convertRect:toView: self (#/bounds self) (#/superview self)))
      (progn
	self)
      +null-ptr+))

(objc:defmethod (#/mouseDown: :void) ((self shape-item-view) event)
  (call-next-method event)
  (when (>= (#/clickCount event) 2)
    (with-slots (shape-list space shape-browser selected-object) (#/delegate (#/window self))
      (let ((sel (#/objectAtIndex: shape-list
				   (#/firstIndex (#/selectionIndexes shape-browser)))))
	(setf selected-object (make-instance 'observer 
					     :object (cp:find-in-space space (lisp-string (#/objectForKey: sel #@"name")))
					     :ignore-slots '(cp::ptr cp::offset)))
	(#/makeKeyAndOrderFront: (shape-editor (#/delegate (#/window self))) self)))))

(objc:defmethod #/init ((wc simple-space-editor))
  (prog1
      (#/initWithWindowNibName: wc #@"SampleArrayEditor")
    (setf (slot-value wc 'shape-list) (#/array ns:ns-mutable-array))))

(defmethod update-shape-list ((self simple-space-editor))
  (let ((shape-list (#/array ns:ns-mutable-array)))
    (dolist (s (cp:shapes (space self)))
      (#/addObject: shape-list (#/dictionaryWithObjectsAndKeys:
				ns:ns-dictionary
				(#/autorelease (ccl::%make-nsstring (cp:name s)))
				#@"name"
				*default-image*
				#@"image"
				+null-ptr+)))
    (#/willChangeValueForKey: self #@"shapeList")
    (setf (slot-value self 'shape-list) shape-list)
    (#/didChangeValueForKey: self #@"shapeList")))

(defmethod initialize-instance :after ((self simple-space-editor) &rest initargs)
  (declare (ignore initargs))
  (update-shape-list self))

(objc:defmethod (#/windowDidLoad :void) ((wc simple-space-editor))
  (#/makeKeyAndOrderFront: (#/window wc) wc))

(defun space-viewer (&optional (space (cp::create-test-space)))
  (gui::execute-in-gui #'(lambda ()
                           (let ((wc (make-instance 'simple-space-editor :space space)))
                             (#/showWindow: wc nil)
			     wc))))

;;; This smells of hack, but it's in Apple's example code so it must be okay!

(defclass icon-view-box (ns:ns-box)
  ()
  (:metaclass ns:+ns-object))

(objc:defmethod (#/hitTest: :id) ((self icon-view-box) point)
  (declare (ignore point))
  +null-ptr+)